package com.wjw.rabbitmq.springbootorderrabbitproducer.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * TTL队列过期时间设置：
 * Direct模式：路由Key模式
 * RabbitMQ配置文件类,创建交换机、创建队列、绑定交换机和队列的关系。
 * 可以在生产者和消费者两边同时配置。
 */
@Configuration
public class TTLRabbitMQConfiguration {

    //1.声明fanout模式的交换机
    @Bean
    public DirectExchange ttlDirectExchange(){
        /**
         * 参数1：交换机名称：来源于OrderService中的名称,要保持一致
         * 参数2：是否持久化
         * 参数3：是否自动删除
         */
        return new DirectExchange("ttl_direct_exchange",true,false);
    }

    /**
     * 置队列过期时间、队列长度、死信交换机、死信交换机的路由key
     *
     * 死信队列相当于接盘侠(为了保证数据的完整性):
     *    超过'过期时长'的消息会进入死信队列
     *    超过'队列长度'的消息会进入死信队列
     *    异常的消息会进入死信队列
     * @return
     */
    @Bean
    public Queue ttlQueueDirect(){
        Map<String,Object> args = new HashMap<>();
        args.put("x-message-ttl",5000);//这里一定是int类型,单位是毫秒,设置该参数后,消息只会才队列中存在5秒,5秒后进入下面配置的死信队列
        args.put("x-max-length",5);//设置该队列的长度为5,表示该队列只能存5条消息,超过5条的消息会进入下面配置的死信队列
        args.put("x-dead-letter-exchange","dead_direct_exchange");//设置死信交换机
        args.put("x-dead-letter-routing-key","dead");//设置死信交换机的路由key,(因为该交换机是direct类型,所以要配路由key;fanout类型无需配置)
        /**
         * 参数1：队列名称
         * 参数2：是否持久化
         */
        return new Queue("ttl.direct.queue",true,false,false,args);
    }

    @Bean
    public Queue ttlMessageQueueDirect(){
        /**
         * 参数1：队列名称
         * 参数2：是否持久化
         */
        return new Queue("ttlmessage.direct.queue",true);
    }

    //3.完成队列和交换机之间的绑定关系,有路由key
    @Bean
    public Binding ttlBindingDirect(){
        return BindingBuilder.bind(ttlQueueDirect()).to(ttlDirectExchange()).with("ttl");
    }

    @Bean
    public Binding ttlMessageBindingDirect(){
        return BindingBuilder.bind(ttlMessageQueueDirect()).to(ttlDirectExchange()).with("ttlmessage");
    }
}

